import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import net.mindview.util.TextFile;

public class E22_WordsInfo2 {

	public static void main(String[] args) {

		Set<WordCounter> wordsSet = new HashSet<WordCounter>();

		for (String word : new TextFile("src/E21_WordsInfo.java", "\\W++")) {
			WordCounter wordCounter = new WordCounter(word);
			if (wordsSet.contains(wordCounter)) {
				updateStat(wordsSet.iterator(), wordCounter);
			} else {
				wordsSet.add(wordCounter);
			}
		}
		List<WordCounter> l = new ArrayList<WordCounter>(wordsSet);
		Collections.sort(l, WordCounter.CASE_INSENSITIVE_ORDER);
		for (WordCounter wc : l)
			System.out.println(wc.getWord() + " => " + wc.getFrequency());

	}

	static void updateStat(Iterator<WordCounter> it, WordCounter wc) {
		while (it.hasNext()) {
			WordCounter currentWC = it.next();
			if (currentWC.equals(wc)) {
				currentWC.incFrequence();
			}
		}
	}
}

class WordCounter {
	public static final Comparator<WordCounter> CASE_INSENSITIVE_ORDER = new Comparator<WordCounter>() {
		@Override
		public int compare(WordCounter o1, WordCounter o2) {
			return o1.word.compareToIgnoreCase(o2.word);
		}
	};

	private final String word;
	private Integer frequency;

	public WordCounter(String word) {
		this.word = word;
		this.frequency = 1;
	}

	public void incFrequence() {
		++frequency;
	}

	public Integer getFrequency() {
		return frequency;
	}

	public void setFrequency(Integer frequency) {
		this.frequency = frequency;
	}

	public String getWord() {
		return word;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof WordCounter)) {
			return false;
		}
		if (!((WordCounter) obj).word.equals(word)) {
			return false;
		}
		return true;
	}

	public int hashCode() {
		return word.hashCode();
	}

	@Override
	public String toString() {
		return word + "==>" + frequency;
	}
}